#pragma once

#ifndef BPF_PSEUDO_MAP_FD
#define BPF_PSEUDO_MAP_FD 1
#endif

#ifndef BPF_PSEUDO_MAP_VALUE
#define BPF_PSEUDO_MAP_VALUE 2
#endif

#ifndef BPF_F_KPROBE_MULTI_RETURN
#define BPF_F_KPROBE_MULTI_RETURN (1U << 0)
#endif

#ifndef BPF_F_UPROBE_MULTI_RETURN
#define BPF_F_UPROBE_MULTI_RETURN (1U << 0)
#endif

// clang-format off
enum bpf_map_type {
	BPF_MAP_TYPE_UNSPEC,
	BPF_MAP_TYPE_HASH,
	BPF_MAP_TYPE_ARRAY,
	BPF_MAP_TYPE_PROG_ARRAY,
	BPF_MAP_TYPE_PERF_EVENT_ARRAY,
	BPF_MAP_TYPE_PERCPU_HASH,
	BPF_MAP_TYPE_PERCPU_ARRAY,
	BPF_MAP_TYPE_STACK_TRACE,
	BPF_MAP_TYPE_CGROUP_ARRAY,
	BPF_MAP_TYPE_LRU_HASH,
	BPF_MAP_TYPE_LRU_PERCPU_HASH,
	BPF_MAP_TYPE_LPM_TRIE,
	BPF_MAP_TYPE_ARRAY_OF_MAPS,
	BPF_MAP_TYPE_HASH_OF_MAPS,
	BPF_MAP_TYPE_DEVMAP,
	BPF_MAP_TYPE_SOCKMAP,
	BPF_MAP_TYPE_CPUMAP,
	BPF_MAP_TYPE_XSKMAP,
	BPF_MAP_TYPE_SOCKHASH,
	BPF_MAP_TYPE_CGROUP_STORAGE,
	BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
	BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
	BPF_MAP_TYPE_QUEUE,
	BPF_MAP_TYPE_STACK,
	BPF_MAP_TYPE_SK_STORAGE,
	BPF_MAP_TYPE_DEVMAP_HASH,
	BPF_MAP_TYPE_STRUCT_OPS,
	BPF_MAP_TYPE_RINGBUF,
	BPF_MAP_TYPE_INODE_STORAGE,
	BPF_MAP_TYPE_TASK_STORAGE,
	BPF_MAP_TYPE_BLOOM_FILTER,
};

enum bpf_prog_type {
	BPF_PROG_TYPE_UNSPEC,
	BPF_PROG_TYPE_SOCKET_FILTER,
	BPF_PROG_TYPE_KPROBE,
	BPF_PROG_TYPE_SCHED_CLS,
	BPF_PROG_TYPE_SCHED_ACT,
	BPF_PROG_TYPE_TRACEPOINT,
	BPF_PROG_TYPE_XDP,
	BPF_PROG_TYPE_PERF_EVENT,
	BPF_PROG_TYPE_CGROUP_SKB,
	BPF_PROG_TYPE_CGROUP_SOCK,
	BPF_PROG_TYPE_LWT_IN,
	BPF_PROG_TYPE_LWT_OUT,
	BPF_PROG_TYPE_LWT_XMIT,
	BPF_PROG_TYPE_SOCK_OPS,
	BPF_PROG_TYPE_SK_SKB,
	BPF_PROG_TYPE_CGROUP_DEVICE,
	BPF_PROG_TYPE_SK_MSG,
	BPF_PROG_TYPE_RAW_TRACEPOINT,
	BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
	BPF_PROG_TYPE_LWT_SEG6LOCAL,
	BPF_PROG_TYPE_LIRC_MODE2,
	BPF_PROG_TYPE_SK_REUSEPORT,
	BPF_PROG_TYPE_FLOW_DISSECTOR,
	BPF_PROG_TYPE_CGROUP_SYSCTL,
	BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE,
	BPF_PROG_TYPE_CGROUP_SOCKOPT,
	BPF_PROG_TYPE_TRACING,
	BPF_PROG_TYPE_STRUCT_OPS,
	BPF_PROG_TYPE_EXT,
	BPF_PROG_TYPE_LSM,
	BPF_PROG_TYPE_SK_LOOKUP,
	BPF_PROG_TYPE_SYSCALL,
};

enum bpf_attach_type {
	BPF_CGROUP_INET_INGRESS,
	BPF_CGROUP_INET_EGRESS,
	BPF_CGROUP_INET_SOCK_CREATE,
	BPF_CGROUP_SOCK_OPS,
	BPF_SK_SKB_STREAM_PARSER,
	BPF_SK_SKB_STREAM_VERDICT,
	BPF_CGROUP_DEVICE,
	BPF_SK_MSG_VERDICT,
	BPF_CGROUP_INET4_BIND,
	BPF_CGROUP_INET6_BIND,
	BPF_CGROUP_INET4_CONNECT,
	BPF_CGROUP_INET6_CONNECT,
	BPF_CGROUP_INET4_POST_BIND,
	BPF_CGROUP_INET6_POST_BIND,
	BPF_CGROUP_UDP4_SENDMSG,
	BPF_CGROUP_UDP6_SENDMSG,
	BPF_LIRC_MODE2,
	BPF_FLOW_DISSECTOR,
	BPF_CGROUP_SYSCTL,
	BPF_CGROUP_UDP4_RECVMSG,
	BPF_CGROUP_UDP6_RECVMSG,
	BPF_CGROUP_GETSOCKOPT,
	BPF_CGROUP_SETSOCKOPT,
	BPF_TRACE_RAW_TP,
	BPF_TRACE_FENTRY,
	BPF_TRACE_FEXIT,
	BPF_MODIFY_RETURN,
	BPF_LSM_MAC,
	BPF_TRACE_ITER,
	BPF_CGROUP_INET4_GETPEERNAME,
	BPF_CGROUP_INET6_GETPEERNAME,
	BPF_CGROUP_INET4_GETSOCKNAME,
	BPF_CGROUP_INET6_GETSOCKNAME,
	BPF_XDP_DEVMAP,
	BPF_CGROUP_INET_SOCK_RELEASE,
	BPF_XDP_CPUMAP,
	BPF_SK_LOOKUP,
	BPF_XDP,
	BPF_SK_SKB_VERDICT,
	BPF_SK_REUSEPORT_SELECT,
	BPF_SK_REUSEPORT_SELECT_OR_MIGRATE,
	BPF_PERF_EVENT,
	BPF_TRACE_KPROBE_MULTI,
	BPF_LSM_CGROUP,
	BPF_STRUCT_OPS,
	BPF_NETFILTER,
	BPF_TCX_INGRESS,
	BPF_TCX_EGRESS,
	BPF_TRACE_UPROBE_MULTI,
	BPF_CGROUP_UNIX_CONNECT,
	BPF_CGROUP_UNIX_SENDMSG,
	BPF_CGROUP_UNIX_RECVMSG,
	BPF_CGROUP_UNIX_GETPEERNAME,
	BPF_CGROUP_UNIX_GETSOCKNAME,
	BPF_NETKIT_PRIMARY,
	BPF_NETKIT_PEER,
	BPF_TRACE_KPROBE_SESSION,
	BPF_TRACE_UPROBE_SESSION,
};

#ifdef __BPF_FUNC_MAPPER
#undef __BPF_FUNC_MAPPER
#endif
#define __BPF_FUNC_MAPPER(FN)			\
	FN(unspec),				\
	FN(map_lookup_elem),			\
	FN(map_update_elem),			\
	FN(map_delete_elem),			\
	FN(probe_read),				\
	FN(ktime_get_ns),			\
	FN(trace_printk),			\
	FN(get_prandom_u32),			\
	FN(get_smp_processor_id),		\
	FN(skb_store_bytes),			\
	FN(l3_csum_replace),			\
	FN(l4_csum_replace),			\
	FN(tail_call),				\
	FN(clone_redirect),			\
	FN(get_current_pid_tgid),		\
	FN(get_current_uid_gid),		\
	FN(get_current_comm),			\
	FN(get_cgroup_classid),			\
	FN(skb_vlan_push),			\
	FN(skb_vlan_pop),			\
	FN(skb_get_tunnel_key),			\
	FN(skb_set_tunnel_key),			\
	FN(perf_event_read),			\
	FN(redirect),				\
	FN(get_route_realm),			\
	FN(perf_event_output),			\
	FN(skb_load_bytes),			\
	FN(get_stackid),			\
	FN(csum_diff),				\
	FN(skb_get_tunnel_opt),			\
	FN(skb_set_tunnel_opt),			\
	FN(skb_change_proto),			\
	FN(skb_change_type),			\
	FN(skb_under_cgroup),			\
	FN(get_hash_recalc),			\
	FN(get_current_task),			\
	FN(probe_write_user),			\
	FN(current_task_under_cgroup),		\
	FN(skb_change_tail),			\
	FN(skb_pull_data),			\
	FN(csum_update),			\
	FN(set_hash_invalid),			\
	FN(get_numa_node_id),			\
	FN(skb_change_head),			\
	FN(xdp_adjust_head),			\
	FN(probe_read_str),			\
	FN(get_socket_cookie),			\
	FN(get_socket_uid),			\
	FN(set_hash),				\
	FN(setsockopt),				\
	FN(skb_adjust_room),			\
	FN(redirect_map),			\
	FN(sk_redirect_map),			\
	FN(sock_map_update),			\
	FN(xdp_adjust_meta),			\
	FN(perf_event_read_value),		\
	FN(perf_prog_read_value),		\
	FN(getsockopt),				\
	FN(override_return),			\
	FN(sock_ops_cb_flags_set),		\
	FN(msg_redirect_map),			\
	FN(msg_apply_bytes),			\
	FN(msg_cork_bytes),			\
	FN(msg_pull_data),			\
	FN(bind),				\
	FN(xdp_adjust_tail),			\
	FN(skb_get_xfrm_state),			\
	FN(get_stack),				\
	FN(skb_load_bytes_relative),		\
	FN(fib_lookup),				\
	FN(sock_hash_update),			\
	FN(msg_redirect_hash),			\
	FN(sk_redirect_hash),			\
	FN(lwt_push_encap),			\
	FN(lwt_seg6_store_bytes),		\
	FN(lwt_seg6_adjust_srh),		\
	FN(lwt_seg6_action),			\
	FN(rc_repeat),				\
	FN(rc_keydown),				\
	FN(skb_cgroup_id),			\
	FN(get_current_cgroup_id),		\
	FN(get_local_storage),			\
	FN(sk_select_reuseport),		\
	FN(skb_ancestor_cgroup_id),		\
	FN(sk_lookup_tcp),			\
	FN(sk_lookup_udp),			\
	FN(sk_release),				\
	FN(map_push_elem),			\
	FN(map_pop_elem),			\
	FN(map_peek_elem),			\
	FN(msg_push_data),			\
	FN(msg_pop_data),			\
	FN(rc_pointer_rel),			\
	FN(spin_lock),				\
	FN(spin_unlock),			\
	FN(sk_fullsock),			\
	FN(tcp_sock),				\
	FN(skb_ecn_set_ce),			\
	FN(get_listener_sock),			\
	FN(skc_lookup_tcp),			\
	FN(tcp_check_syncookie),		\
	FN(sysctl_get_name),			\
	FN(sysctl_get_current_value),		\
	FN(sysctl_get_new_value),		\
	FN(sysctl_set_new_value),		\
	FN(strtol),				\
	FN(strtoul),				\
	FN(sk_storage_get),			\
	FN(sk_storage_delete),			\
	FN(send_signal),			\
	FN(tcp_gen_syncookie),			\
	FN(skb_output),				\
	FN(probe_read_user),			\
	FN(probe_read_kernel),			\
	FN(probe_read_user_str),		\
	FN(probe_read_kernel_str),		\
	FN(tcp_send_ack),			\
	FN(send_signal_thread),			\
	FN(jiffies64),				\
	FN(read_branch_records),		\
	FN(get_ns_current_pid_tgid),		\
	FN(xdp_output),				\
	FN(get_netns_cookie),			\
	FN(get_current_ancestor_cgroup_id),	\
	FN(sk_assign),				\
	FN(ktime_get_boot_ns),			\
	FN(seq_printf),				\
	FN(seq_write),				\
	FN(sk_cgroup_id),			\
	FN(sk_ancestor_cgroup_id),		\
	FN(ringbuf_output),			\
	FN(ringbuf_reserve),			\
	FN(ringbuf_submit),			\
	FN(ringbuf_discard),			\
	FN(ringbuf_query),			\
	FN(csum_level),				\
	FN(skc_to_tcp6_sock),			\
	FN(skc_to_tcp_sock),			\
	FN(skc_to_tcp_timewait_sock),		\
	FN(skc_to_tcp_request_sock),		\
	FN(skc_to_udp6_sock),			\
	FN(get_task_stack),			\
	FN(load_hdr_opt),			\
	FN(store_hdr_opt),			\
	FN(reserve_hdr_opt),			\
	FN(inode_storage_get),			\
	FN(inode_storage_delete),		\
	FN(d_path),				\
	FN(copy_from_user),			\
	FN(snprintf_btf),			\
	FN(seq_printf_btf),			\
	FN(skb_cgroup_classid),			\
	FN(redirect_neigh),			\
	FN(per_cpu_ptr),			\
	FN(this_cpu_ptr),			\
	FN(redirect_peer),			\
	FN(task_storage_get),			\
	FN(task_storage_delete),		\
	FN(get_current_task_btf),		\
	FN(bprm_opts_set),			\
	FN(ktime_get_coarse_ns),		\
	FN(ima_inode_hash),			\
	FN(sock_from_file),			\
	FN(check_mtu),				\
	FN(for_each_map_elem),			\
	FN(snprintf),				\
	FN(sys_bpf),				\
	FN(btf_find_by_name_kind),		\
	FN(sys_close),				\
	FN(timer_init),				\
	FN(timer_set_callback),			\
	FN(timer_start),			\
	FN(timer_cancel),			\
	FN(get_func_ip),			\
	FN(get_attach_cookie),			\
	FN(task_pt_regs),			\
	FN(get_branch_snapshot),		\
	FN(trace_vprintk),			\
	FN(skc_to_unix_sock),			\
	FN(kallsyms_lookup_name),		\
	FN(find_vma),				\
	FN(loop),				\
	FN(strncmp),				\
	FN(get_func_arg),			\
	FN(get_func_ret),			\
	FN(get_func_arg_cnt),			\
	FN(get_retval),				\
	FN(set_retval),				\
	FN(xdp_get_buff_len),			\
	FN(xdp_load_bytes),			\
	FN(xdp_store_bytes),			\
	FN(copy_from_user_task),		\
	FN(skb_set_tstamp),			\
	FN(ima_file_hash),			\
	FN(kptr_xchg),				\
	FN(map_lookup_percpu_elem),		\
	FN(skc_to_mptcp_sock),			\
	FN(dynptr_from_mem),			\
	FN(ringbuf_reserve_dynptr),		\
	FN(ringbuf_submit_dynptr),		\
	FN(ringbuf_discard_dynptr),		\
	FN(dynptr_read),			\
	FN(dynptr_write),			\
	FN(dynptr_data),			\
	FN(tcp_raw_gen_syncookie_ipv4),		\
	FN(tcp_raw_gen_syncookie_ipv6),		\
	FN(tcp_raw_check_syncookie_ipv4),	\
	FN(tcp_raw_check_syncookie_ipv6),	\
	FN(ktime_get_tai_ns),			\
	FN(user_ringbuf_drain),			\
	FN(cgrp_storage_get),			\
	FN(cgrp_storage_delete),


// integer value in 'imm' field of BPF_CALL instruction selects which helper
// function eBPF program intends to call
#define __BPF_ENUM_FN(x) BPF_FUNC_ ## x
enum bpf_func_id {
	__BPF_FUNC_MAPPER(__BPF_ENUM_FN)
	__BPF_FUNC_MAX_ID,
};
#undef __BPF_ENUM_FN

#define BPFTRACE_LIBBPF_OPTS(TYPE, NAME, ...)                                  \
  _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"")           \
      LIBBPF_OPTS(TYPE, NAME, __VA_ARGS__)

// clang-format on
